{% extends "base.html" %}

{% block title %}任务管理 - XbyJob{% endblock %}

{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
    <h1 class="h2">任务管理</h1>
    <a href="{{ url_for('dashboard.new_task') }}" class="btn btn-primary">
        <i class="fas fa-plus me-1"></i>创建任务
    </a>
</div>

<!-- 筛选器 -->
<div class="row mb-3">
    <div class="col-md-4">
        <select class="form-select" id="statusFilter">
            <option value="">全部状态</option>
            <option value="enabled">已启用</option>
            <option value="disabled">已禁用</option>
        </select>
    </div>
    <div class="col-md-6">
        <input type="text" class="form-control" id="searchInput" placeholder="搜索任务名称...">
    </div>
    <div class="col-md-2">
        <button type="button" class="btn btn-outline-primary w-100" onclick="applyFilters()">
            <i class="fas fa-filter me-1"></i>筛选
        </button>
    </div>
</div>

<!-- 任务列表 -->
<div class="card">
    <div class="card-body">
        <div class="table-responsive">
            <table class="table table-striped" id="tasksTable">
                <thead>
                    <tr>
                        <th>名称</th>
                        <th>类型</th>
                        <th>状态</th>
                        <th>Cron表达式</th>
                        <th>下次执行</th>
                        <th>最后执行时间</th>
                        <th>今日执行</th>
                        <th>今日成功</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td colspan="9" class="text-center">
                            <div class="spinner-border text-primary" role="status">
                                <span class="visually-hidden">加载中...</span>
                            </div>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
        
        <!-- 分页 -->
        <nav aria-label="任务分页">
            <ul class="pagination justify-content-center" id="pagination">
            </ul>
        </nav>
    </div>
</div>



<!-- Cron帮助模态框 -->
<div class="modal fade" id="cronHelpModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Cron表达式帮助</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <h6>格式说明</h6>
                <p>Cron表达式由5个字段组成，用空格分隔：</p>
                <code>分钟 小时 日 月 星期</code>
                
                <h6 class="mt-3">字段范围</h6>
                <ul>
                    <li>分钟: 0-59</li>
                    <li>小时: 0-23</li>
                    <li>日: 1-31</li>
                    <li>月: 1-12</li>
                    <li>星期: 0-7 (0和7都表示周日)</li>
                </ul>
                
                <h6 class="mt-3">特殊字符</h6>
                <ul>
                    <li><code>*</code> 表示任意值</li>
                    <li><code>,</code> 表示列表，如 1,3,5</li>
                    <li><code>-</code> 表示范围，如 1-5</li>
                    <li><code>/</code> 表示步长，如 */5 表示每5个单位</li>
                </ul>
                
                <h6 class="mt-3">常用示例</h6>
                <table class="table table-sm">
                    <tr><td><code>0 0 * * *</code></td><td>每天午夜执行</td></tr>
                    <tr><td><code>*/5 * * * *</code></td><td>每5分钟执行</td></tr>
                    <tr><td><code>0 9 * * 1-5</code></td><td>工作日上午9点执行</td></tr>
                    <tr><td><code>0 0 1 * *</code></td><td>每月1号午夜执行</td></tr>
                    <tr><td><code>0 */2 * * *</code></td><td>每2小时执行</td></tr>
                </table>
            </div>
        </div>
    </div>
</div>

<!-- 环境变量帮助模态框 -->
<div class="modal fade" id="envVarHelpModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">环境变量使用帮助</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <h6>什么是环境变量？</h6>
                <p>环境变量是在任务执行时提供给脚本或命令的运行时配置参数。</p>
                
                <h6 class="mt-3">使用场景</h6>
                <ul>
                    <li><strong>配置脚本行为</strong>: 控制日志级别、指定配置文件路径等</li>
                    <li><strong>敏感信息管理</strong>: 传递API密钥、数据库密码等敏感信息</li>
                    <li><strong>环境区分</strong>: 区分开发、测试、生产环境</li>
                    <li><strong>资源定位</strong>: 指定数据文件路径、临时目录等</li>
                </ul>
                
                <h6 class="mt-3">访问方式</h6>
                <div class="card mb-3">
                    <div class="card-header">
                        <strong>Python脚本</strong>
                    </div>
                    <div class="card-body">
                        <pre class="bg-light p-2 rounded"><code>import os

# 获取环境变量
api_key = os.environ.get('API_KEY')
database_url = os.environ.get('DATABASE_URL')

# 设置默认值
log_level = os.environ.get('LOG_LEVEL', 'INFO')

# 使用环境变量
print(f"API Key: {api_key}")
print(f"Database URL: {database_url}")
print(f"Log Level: {log_level}")</code></pre>
                    </div>
                </div>
                
                <div class="card">

                    <div class="card-body">
                        <pre class="bg-light p-2 rounded"><code>#!/bin/bash

# 直接使用环境变量
echo "API Key: $API_KEY"
echo "Database URL: $DATABASE_URL"
echo "Log Level: $LOG_LEVEL"

# 检查环境变量是否存在
if [ -z "$API_KEY" ]; then
    echo "错误: 未设置API_KEY环境变量"
    exit 1
fi

# 使用环境变量执行操作
curl -H "Authorization: Bearer $API_KEY" $API_ENDPOINT</code></pre>
                    </div>
                </div>
                
                <h6 class="mt-3">示例</h6>
                <p>添加以下环境变量：</p>
                <ul>
                    <li><strong>API_KEY</strong>: abc123def456</li>
                    <li><strong>DATABASE_URL</strong>: postgresql://user:pass@localhost/db</li>
                    <li><strong>LOG_LEVEL</strong>: DEBUG</li>
                </ul>
            </div>
        </div>
    </div>
</div>

{% endblock %}

{% block extra_js %}
<script>
let currentPage = 1;
let currentFilters = {};
let editingTaskId = null;

$(document).ready(function() {
    loadTasks();
    

});

function loadTasks(page = 1) {
    currentPage = page;
    
    const params = new URLSearchParams({
        page: page,
        per_page: 20,
        ...currentFilters
    });
    
    $('#tasksTable tbody').html(`
        <tr>
            <td colspan="7" class="text-center">
                <div class="spinner-border text-primary" role="status">
                    <span class="visually-hidden">加载中...</span>
                </div>
            </td>
        </tr>
    `);
    
    $.get('/api/tasks?' + params.toString())
        .done(function(response) {
            if (response.success) {
                renderTasks(response.data.tasks);
                renderPagination(response.data.pagination);
            } else {
                showAlert('获取任务列表失败: ' + response.message, 'danger');
            }
        })
        .fail(function() {
            showAlert('网络错误，请稍后重试', 'danger');
        });
}

function renderTasks(tasks) {
    const tbody = $('#tasksTable tbody');
    tbody.empty();
    
    if (tasks.length === 0) {
        tbody.append(`
            <tr>
                <td colspan="9" class="text-center text-muted">暂无任务</td>
            </tr>
        `);
        return;
    }
    
    tasks.forEach(function(task) {
        const statusBadge = task.is_enabled ? 
            '<span class="badge bg-success">已启用</span>' : 
            '<span class="badge bg-secondary">已禁用</span>';
        
        const typeBadge = getTaskTypeBadge(task.task_type);
        
        const nextRun = task.next_run_at ? 
            new Date(task.next_run_at).toLocaleString() : '-';
        
        const lastRun = task.last_started_at ? 
            new Date(task.last_started_at).toLocaleString() : '-';
        
        // 今日执行统计显示
        const todayExecutions = task.today_executions || 0;
        const todaySuccess = task.today_success || 0;
        const todayExecutionsBadge = todayExecutions > 0 ? 
            `<span class="badge bg-info">${todayExecutions}</span>` : 
            `<span class="text-muted">0</span>`;
        const todaySuccessBadge = todaySuccess > 0 ? 
            `<span class="badge bg-success">${todaySuccess}</span>` : 
            `<span class="text-muted">0</span>`;
        
        tbody.append(`
            <tr>
                <td>
                    <div class="fw-bold">${task.name}</div>
                    <small class="text-muted">${task.description || ''}</small>
                </td>
                <td>${typeBadge}</td>
                <td>${statusBadge}</td>
                <td><code>${task.cron_expression}</code></td>
                <td>${nextRun}</td>
                <td>${lastRun}</td>
                <td class="text-center">${todayExecutionsBadge}</td>
                <td class="text-center">${todaySuccessBadge}</td>
                <td>
                    <div class="btn-group btn-group-sm">
                        <button class="btn btn-outline-primary" onclick="editTask(${task.id})" title="编辑">
                            编辑
                        </button>
                        <button class="btn btn-outline-success" onclick="executeTask(${task.id}, event)" title="立即执行">
                            执行
                        </button>
                        <button class="btn btn-outline-info" onclick="viewTask(${task.id})" title="详情">
                            详情
                        </button>
                        <button class="btn btn-outline-warning" onclick="toggleTask(${task.id}, ${task.is_enabled})" 
                                title="${task.is_enabled ? '禁用' : '启用'}">
                            ${task.is_enabled ? '禁用' : '启用'}
                        </button>
                        <button class="btn btn-outline-danger" onclick="deleteTask(${task.id})" title="删除">
                            删除
                        </button>
                    </div>
                </td>
            </tr>
        `);
    });
}

function renderPagination(pagination) {
    const nav = $('#pagination');
    nav.empty();
    
    if (pagination.pages <= 1) return;
    
    // 上一页
    nav.append(`
        <li class="page-item ${!pagination.has_prev ? 'disabled' : ''}">
            <a class="page-link" href="#" onclick="loadTasks(${pagination.page - 1})">上一页</a>
        </li>
    `);
    
    // 页码
    const startPage = Math.max(1, pagination.page - 2);
    const endPage = Math.min(pagination.pages, pagination.page + 2);
    
    for (let i = startPage; i <= endPage; i++) {
        nav.append(`
            <li class="page-item ${i === pagination.page ? 'active' : ''}">
                <a class="page-link" href="#" onclick="loadTasks(${i})">${i}</a>
            </li>
        `);
    }
    
    // 下一页
    nav.append(`
        <li class="page-item ${!pagination.has_next ? 'disabled' : ''}">
            <a class="page-link" href="#" onclick="loadTasks(${pagination.page + 1})">下一页</a>
        </li>
    `);
}

function applyFilters() {
    currentFilters = {};
    
    const status = $('#statusFilter').val();
    if (status) currentFilters.status = status;
    
    const search = $('#searchInput').val().trim();
    if (search) currentFilters.search = search;
    
    loadTasks(1);
}



function editTask(taskId) {
    window.location.href = `/dashboard/tasks/${taskId}/edit`;
}



function deleteTask(taskId) {
    if (!confirm('确定要删除这个任务吗？此操作不可恢复。')) {
        return;
    }
    
    $.ajax({
        url: `/api/tasks/${taskId}`,
        method: 'DELETE'
    })
    .done(function(response) {
        if (response.success) {
            showAlert('任务删除成功', 'success');
            loadTasks(currentPage);
        } else {
            showAlert('删除失败: ' + response.message, 'danger');
        }
    })
    .fail(function() {
        showAlert('网络错误，请稍后重试', 'danger');
    });
}

function toggleTask(taskId, currentStatus) {
    const action = currentStatus ? '禁用' : '启用';
    
    $.ajax({
        url: `/api/tasks/${taskId}/toggle`,
        method: 'POST'
    })
    .done(function(response) {
        if (response.success) {
            showAlert(`任务${action}成功`, 'success');
            loadTasks(currentPage);
        } else {
            showAlert(`${action}失败: ` + response.message, 'danger');
            console.log(`${action}失败详情:`, response);
        }
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
        // 记录详细的错误信息
        console.error(`任务${action}请求失败:`);
        console.error('状态码:', jqXHR.status);
        console.error('状态文本:', jqXHR.statusText);
        console.error('响应内容:', jqXHR.responseText);
        console.error('错误类型:', textStatus);
        console.error('异常信息:', errorThrown);
        
        // 尝试解析响应JSON
        let errorDetails = '';
        try {
            const responseData = JSON.parse(jqXHR.responseText);
            console.error('服务器返回的JSON错误信息:', responseData);
            if (responseData.message) {
                errorDetails = `: ${responseData.message}`;
            } else if (responseData.error) {
                errorDetails = `: ${responseData.error}`;
            }
        } catch (e) {
            console.error('无法解析响应JSON:', e);
            // 如果响应不是JSON，直接显示响应文本
            if (jqXHR.responseText) {
                errorDetails = `: ${jqXHR.responseText}`;
            }
        }
        
        const errorMsg = `网络错误 (${jqXHR.status})${errorDetails}`;
        showAlert(errorMsg, 'danger');
    });
}

function executeTask(taskId, event) {
    // 阻止事件冒泡
    if (event) {
        event.preventDefault();
        event.stopPropagation();
    }
    
    $.ajax({
        url: `/api/tasks/${taskId}/execute`,
        method: 'POST'
    })
    .done(function(response) {
        if (response.success) {
            showAlert('任务已提交执行', 'success');
        } else {
            showAlert('执行失败: ' + response.message, 'danger');
            console.log('执行失败详情:', response);
        }
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
        // 记录详细的错误信息
        console.error('任务执行请求失败:');
        console.error('状态码:', jqXHR.status);
        console.error('状态文本:', jqXHR.statusText);
        console.error('响应内容:', jqXHR.responseText);
        console.error('错误类型:', textStatus);
        console.error('异常信息:', errorThrown);
        
        // 尝试解析响应JSON
        let errorDetails = '';
        try {
            const responseData = JSON.parse(jqXHR.responseText);
            console.error('服务器返回的JSON错误信息:', responseData);
            if (responseData.message) {
                errorDetails = `: ${responseData.message}`;
            } else if (responseData.error) {
                errorDetails = `: ${responseData.error}`;
            }
        } catch (e) {
            console.error('无法解析响应JSON:', e);
            // 如果响应不是JSON，直接显示响应文本
            if (jqXHR.responseText) {
                errorDetails = `: ${jqXHR.responseText}`;
            }
        }
        
        const errorMsg = `网络错误 (${jqXHR.status})${errorDetails}`;
        showAlert(errorMsg, 'danger');
        console.log('请求失败详情:', {
            status: jqXHR.status,
            statusText: jqXHR.statusText,
            responseText: jqXHR.responseText,
            error: errorThrown
        });
        
        // 尝试解析响应JSON
        try {
            const responseData = JSON.parse(jqXHR.responseText);
            console.log('服务器返回的错误信息:', responseData);
            if (responseData && responseData.message) {
                showAlert(`服务器错误: ${responseData.message}`, 'danger');
            }
        } catch (e) {
            console.log('无法解析响应JSON:', e);
        }
    });
}

function viewTask(taskId) {
    window.location.href = `/dashboard/tasks/${taskId}/detail`;
}









function getTaskTypeBadge(type) {
    const badges = {
        'python_script': '<span class="badge bg-primary">Python</span>',

    };
    return badges[type] || `<span class="badge bg-secondary">${type}</span>`;
}







// 移除与依赖包相关的函数

function showAlert(message, type) {
    // 使用基础模板中定义的全局showMessage函数（即showToast）
    if (typeof window.showMessage === 'function') {
        // 映射类型到Toast支持的类型
        let toastType = type;
        switch(type) {
            case 'danger':
                toastType = 'error';
                break;
            case 'warning':
                toastType = 'warning';
                break;
            case 'success':
                toastType = 'success';
                break;
            default:
                toastType = 'info';
        }
        showMessage(message, toastType, 3000);
    } else {
        // 如果全局函数不可用，回退到原来的实现
        const alertHtml = `
            <div class="alert alert-${type} alert-dismissible fade show" role="alert">
                ${message}
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            </div>
        `;
        
        $('.container-fluid').prepend(alertHtml);
        
        // 3秒后自动消失
        setTimeout(function() {
            $('.alert').alert('close');
        }, 3000);
    }
}
</script>
{% endblock %}
